package org.tulkas.webclient.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

/**
 * @author <a href="mailto:tulkas.web@gmail.com">Tulkas</a>
 *
 */
public abstract class IOUtil {
	private static int BUFFER_SIZE = 1024;

	/**
	 * read the data bytes from an inputStream to an outputStream, until there is no byte that can be read.
	 *
	 * @param in
	 * @param out
	 * @throws IOException
	 */
	public static void readAndWrite(InputStream in, OutputStream out)
			throws IOException {
		byte[] buffer = new byte[BUFFER_SIZE];
		int read;
		while (true) {
			read = in.read(buffer);
			if (read <= 0)
				break;
			out.write(buffer, 0, read);
		}
	}

	/**
	 * read the data chars from a reader to a writer, until there is no char that can be read.
	 * 
	 * @param in
	 * @param out
	 * @throws IOException
	 */
	public static void readAndWrite(Reader in, Writer out) throws IOException {
		char[] buffer = new char[BUFFER_SIZE];
		int read;
		while (true) {
			read = in.read(buffer);
			if (read <= 0)
				break;
			out.write(buffer, 0, read);
		}
	}

	/**
	 * read the data from an inputstream into a byte array.
	 * 
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static byte[] readBytes(InputStream in) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		readAndWrite(in, out);
		byte[] bytes = out.toByteArray();
		out.close();
		return bytes;
	}

	/**
	 * write the data from a byte array into an outputStream.
	 * 
	 * @param out
	 * @param bytes
	 * @throws IOException
	 */
	public static void writeBytes(OutputStream out, byte[] bytes)
			throws IOException {
		ByteArrayInputStream in = new ByteArrayInputStream(bytes);
		readAndWrite(in, out);
		in.close();
	}

	/**
	 * read the chars from a reader and construct a string from the chars.
	 * 
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static String readString(Reader in) throws IOException {
		StringWriter out = new StringWriter();
		readAndWrite(in, out);
		String ret = out.toString();
		out.close();
		return ret;
	}

	/**
	 * write the chars in a string into a writer.
	 * 
	 * @param out
	 * @param string
	 * @throws IOException
	 */
	public static void writeString(Writer out, String str) throws IOException {
		StringReader in = new StringReader(str);
		readAndWrite(in, out);
		in.close();
	}

	public static String readStringFromRes(String resLocation, String encoding)
			throws Exception {
		InputStream is = IOUtil.class.getResourceAsStream(resLocation);
		if (encoding == null) {
			return new String(IOUtil.readBytes(is));
		} else {
			return new String(IOUtil.readBytes(is), encoding);
		}
	}

}
